package com.gzhu.knowledgeAdmin.service.impl;

import com.gzhu.knowledgeAdmin.dao.TableMapper;
import com.gzhu.knowledgeAdmin.entity.Column;
import com.gzhu.knowledgeAdmin.entity.TableLabel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

@Service
public class TableService {

    private static final Logger logger = LoggerFactory.getLogger(TableService.class);

    @Resource
    private TableMapper tableMapper;

    public List<String> getAllTableNames() {
        return tableMapper.getAllTableNames();
    }

    public List<Map<String, Object>> getTableData(String tableName) {
        List<String> allTableNames = getAllTableNames();
        if (!allTableNames.contains(tableName)) {
            throw new IllegalArgumentException("Invalid table name: " + tableName);
        }
        return tableMapper.getTableData(tableName);
    }

    public List<Column> getTableColumns(String tableName) {
        List<String> allTableNames = getAllTableNames();
        if (!allTableNames.contains(tableName)) {
            throw new IllegalArgumentException("Invalid table name: " + tableName);
        }
        List<Column> columns = tableMapper.getTableColumns(tableName);
        logger.info("Columns for table {}: {}", tableName, columns);
        if (columns == null || columns.isEmpty()) {
            throw new IllegalArgumentException("No columns found for table: " + tableName);
        }
        return columns;
    }

    public List<Map<String, Object>> searchTableData(String tableName, List<String> columns, String searchTerm) {
        String query = buildSearchQuery(tableName, columns, searchTerm);
        return tableMapper.executeSearchQuery(query);
    }

    public String buildSearchQuery(String tableName, List<String> columnNames, String searchTerm) {
        if (columnNames == null || columnNames.isEmpty()) {
            throw new IllegalArgumentException("No columns selected for search");
        }
        String escapedTableName = escapeSql(tableName);
        String escapedSearchTerm = escapeSql(searchTerm);
        StringBuilder query = new StringBuilder("SELECT * FROM " + escapedTableName + " WHERE ");
        for (int i = 0; i < columnNames.size(); i++) {
            String escapedColumnName = escapeSql(columnNames.get(i));
            query.append(escapedColumnName).append(" LIKE '%").append(escapedSearchTerm).append("%' ");
            if (i < columnNames.size() - 1) {
                query.append("OR ");
            }
        }
        return query.toString();
    }

    private String escapeSql(String input) {
        return input.replace("'", "''");
    }

    private boolean hasFIdColumn(String tableName) {
        List<Column> columns = getTableColumns(tableName);
        for (Column column : columns) {
            if ("f_id".equalsIgnoreCase(column.getName())) {
                return true;
            }
        }
        return false;
    }

    @Transactional
    public void insertDataIntoTable(String tableName, Map<String, Object> data) {
        List<String> allTableNames = getAllTableNames();
        if (!allTableNames.contains(tableName)) {
            throw new IllegalArgumentException("Invalid table name: " + tableName);
        }
        boolean hasFId = hasFIdColumn(tableName);

        if (hasFId) {
            data.remove("f_id");
        }

        logger.info("Inserting data into table {}: {}", tableName, data);
        try {
            tableMapper.insertDataIntoTable(tableName, data);
        } catch (Exception e) {
            logger.error("Error inserting data into table {}: {}", tableName, e.getMessage(), e);
            throw new RuntimeException("Internal Server Error: " + e.getMessage());
        }
    }

    @Transactional
    public int deleteRowsByIds(String tableName, List<Integer> idsToDelete) {
        List<String> allTableNames = getAllTableNames();
        if (!allTableNames.contains(tableName)) {
            throw new IllegalArgumentException("Invalid table name: " + tableName);
        }
        if (!hasFIdColumn(tableName)) {
            throw new IllegalArgumentException("Table " + tableName + " does not have f_id column");
        }
        return tableMapper.deleteRowsByIds(tableName, idsToDelete);
    }

    @Transactional
    public int updateRecord(String tableName, Integer id, Map<String, Object> data) {
        List<String> allTableNames = getAllTableNames();
        if (!allTableNames.contains(tableName)) {
            throw new IllegalArgumentException("Invalid table name: " + tableName);
        }
        if (!hasFIdColumn(tableName)) {
            throw new IllegalArgumentException("Table " + tableName + " does not have f_id column");
        }
        return tableMapper.updateRecord(tableName, id, data);
    }

    public List<TableLabel> findAllTableLabels() {
        return tableMapper.findAllTableLabels();
    }

    public String getDisplayTableName(String actualTableName) {
        List<TableLabel> labels = findAllTableLabels();
        for (TableLabel label : labels) {
            if (label.getTableName().equals(actualTableName)) {
                return label.getLabel();
            }
        }
        return actualTableName;
    }
}
